using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Forest.Cat.Domain.Entities;
using Forest.Core;
using Forest.Core.Caching;
using Forest.Core.Data;
using Forest.Core.Events;
using Forest.Cat.Domain.Shared;

namespace Forest.Cat.Domain.Services.Links
{
    public partial class LinkService : ILinkService
    {
        #region Constants
        private const string LINK_BY_ID_KEY = "link.id-{0}";
        private const string LINK_PATTERN_KEY = "link.";
        #endregion

        #region Fields
        private readonly IRepository<Link> _linkRepository;
        private readonly ICacheManager _cacheManager;
        private readonly IEventPublisher _eventPublisher;
        #endregion

        #region Ctor
        public LinkService(IRepository<Link> linkRepository, ICacheManager cacheManager, IEventPublisher eventPublisher)
        {
            _linkRepository = linkRepository;
            _cacheManager = cacheManager;
            _eventPublisher = eventPublisher;
        }
        #endregion

        #region Base Methods
        public virtual void DeleteLink(Link link)
        {
            if (link == null)
                throw new ArgumentNullException("Link");

            _linkRepository.Delete(link);
            _cacheManager.RemoveByPattern(LINK_PATTERN_KEY);
            _eventPublisher.EntityDeleted(link);
        }

        public Link GetLinkById(Guid linkId)
        {
            if (linkId == Guid.Empty)
                return null;
            string key = string.Format(LINK_BY_ID_KEY, linkId);

            return _cacheManager.Get(key, () =>
            {
                var cl = _linkRepository.GetById(linkId);
                return cl;
            });
        }

        public virtual IPagedList<Link> GetAllLinks(int pageIndex, int pageSize)
        {
            var query = _linkRepository.Table;
            query = query.OrderBy(w => w.Id);
            var items = new PagedList<Link>(query, pageIndex, pageSize);
            return items;
        }

        public virtual void InsertLink(Link link)
        {
            if (link == null)
                throw new ArgumentNullException("Link");
            _linkRepository.Insert(link);
            _cacheManager.RemoveByPattern(LINK_PATTERN_KEY);
            _eventPublisher.EntityInserted(link);
        }

        public virtual void UpdateLink(Link link)
        {
            if (link == null)
                throw new ArgumentNullException("Link");
            _linkRepository.Update(link);
            _cacheManager.RemoveByPattern(LINK_PATTERN_KEY);
            _eventPublisher.EntityUpdated(link);
        }
        #endregion

        #region Extend Methods
        public IList<Link> GetLinkList(bool? isPost)
        {
            var query = _linkRepository.Table;
            if (isPost.HasValue)
            {
                query = query.Where(x => x.IsPosted.Value.Equals(isPost.Value));
            }
            return query.ToList();
        }
        #endregion
    }
}
